package org.NooLab.itexx.browser;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import org.NooLab.itexx.retrieval.PageIntf;
import org.NooLab.utilities.logging.PrintLog;

import chrriis.dj.nativeswing.swtimpl.components.JWebBrowser;
import chrriis.dj.nativeswing.swtimpl.components.WebBrowserNavigationParameters;

public class BrowserWorker extends javax.swing.SwingWorker<ArrayList<String>, String> {
	
	private static final int _BY_URL = 1;
	private static final int _BY_HTML = 2;

	
	JWebBrowser webBrowser;
	DjBrowserHost djBrowserHost;
	DjBrowserListener listener;
	
	PageIntf page;
	
	String client="";
	boolean retrieveContentOnly = false;
	String htmlContent="";
	
	
	boolean workerIsRunning=false, clearDisplay=false;
	String baseurl="";
	
	int mode = 0;
	

	// ========================================================================
	public BrowserWorker( DjBrowserHost djBrowserHost, JWebBrowser webBrowser, String url) {
		
		baseurl = url;
		this.webBrowser = webBrowser;
		this.djBrowserHost = djBrowserHost;
		mode = _BY_URL;
	}

	// The first template argument, in this case, ArrayList<Integer>, is
	// what is returned by doInBackground(), and by get().
	//
	// The second template argument, in this case, Integer, is what
	// is published with the publish method. It is also the data
	// type which is stored by the java.util.List that is the parameter
	// for the process method, which receives the information published
	// by the publish method.
	
	public BrowserWorker(JWebBrowser webbrowser, PageIntf page, DjBrowserListener listener) {
		// 
		webBrowser = webbrowser;
		this.page = page;
		this.listener = listener;
		
		
		mode = _BY_HTML;
		
		// if the page comes as an explicit null, we clear the display
		if (page==null){
			clearDisplay=true;
		}else{
			client = listener.getInternalClient();
			if (client.contains("RetrievalDispatch")==false){
				baseurl = page.getContextUrl() ;
			}
		}
	}

	/** get content of webBrowser  */
	public BrowserWorker( DjBrowserHost djBrowserHost, JWebBrowser webBrowser) {
		// 
		this.webBrowser = webBrowser;
		retrieveContentOnly = true;
	}
	// ========================================================================

	protected ArrayList<String> doInBackground() {
		// Returns items of the type given as the first template
		// argument to the SwingWorker class.

		if (javax.swing.SwingUtilities.isEventDispatchThread()){
			System.out.println("javax.swing.SwingUtilities.isEventDispatchThread() returned true.");
		}
		
		workerIsRunning = true;
		/*
		while ((appIsRunning) && (workerIsRunning)){
			PrintLog.Delay(100);
		}
		*/
		
		String tmpValue = "...";
		ArrayList<String> list = new ArrayList<String>();

			publish("");// Integer(i));
			list.add(tmpValue);
		
		return list;
	}

	// Note, always use java.util.List here, or it will use the wrong list.

	protected void process(java.util.List<String> progressList) {
		// This method is processing a java.util.List of items
		// given as successive arguments to the publish method.
		// Note that these calls are coalesced into a java.util.List.
		// This list holds items of the type given as the
		// second template parameter type to SwingWorker.
		// Note that the get method below has nothing to do
		// with the SwingWorker get method; it is the List's
		// get method.
		// This would be a good place to update a progress bar.
		
		if (!javax.swing.SwingUtilities.isEventDispatchThread()){
			System.out.println("javax.swing.SwingUtilities.isEventDispatchThread() returned false.");
		}

		//Integer percentComplete = progressList.get(progressList.size() - 1);
		// progressBar.setValue(percentComplete.intValue());
		
		// ?? downloadBinaryDocument
	
		if (retrieveContentOnly){
			if (webBrowser!=null){
				htmlContent = webBrowser.getHTMLContent() ;
			}
			return ;
		}
		
		if (client.contains("RetrievalDispatch")==false){
			navigateToHtml(baseurl) ;
		}else{
		
			if (page!=null){
				showHtml( page.getHTML()) ;
			}
		}
		
	}

	private void showHtml(String html) {

		if (html.length()>4){
			webBrowser.setHTMLContent(html);
		}else{
		}
	}

	
	
	private void navigateToHtml(String baseurl) {

		if (retrieveContentOnly){
			
			if (webBrowser!=null){
				htmlContent = webBrowser.getHTMLContent() ;
				return;
			}
			
		}
		if ((clearDisplay) ){
			webBrowser.setHTMLContent("");
			return;
		}
		if (baseurl.length()==0){
			// return;
		}
		if ((baseurl==null) || (baseurl.length()<=1)){
			try {
				
				throw(new Exception("Unexpected condition in BrowserWorker: requested url is null or empty, BrowserWorker will stop."));
				
			} catch (Exception e) {
				System.err.println("\n"+e.getMessage()+"\n");
			}
		}else{
			webBrowser.navigate(baseurl, browserParameters());
			
			if (djBrowserHost!=null){
				// djBrowserHost.getListener().reset();
			}
			
		}
		
	}

	private WebBrowserNavigationParameters browserParameters() {
		// 
		
		WebBrowserNavigationParameters parameters = new WebBrowserNavigationParameters();
		
		Map<String, String> headersMap = new HashMap<String, String>();
		headersMap.put("User-agent", UserAgents.getRandomSelection());
		// headersMap.put(testHeaderKeyTextField.getText(), testHeaderValueTextField.getText());
		parameters.setHeaders(headersMap);
		
		return parameters;
	}

	private void downloadBinaryDocument(){

		// use this in case of pdf .... 
		/*
		WebRetriever webRetriever;
		webRetriever = new WebRetriever();
		
		webRetriever.setUrlStr(requestUrl, "");
		String str = webRetriever.getHtml();
		if (str.contains("</html>")==false){
			str = str+"</html>";
		}
		
		app.windowGui.out.print(2,"page downloaded, len="+str.length());
		
		listener.close();
		webBrowser.removeWebBrowserListener(listener) ;
		
		prepare( app) ;
		*/
	}
	protected void done() {
		PrintLog.Print(3,"doInBackground is complete");
		
		
		if (!javax.swing.SwingUtilities.isEventDispatchThread()){
			System.out.println("javax.swing.SwingUtilities.isEventDispatchThread() returned false.");
		}

		try {

			if (retrieveContentOnly){
				htmlContent = webBrowser.getHTMLContent() ;
				return;
			}

			String str = webBrowser.getHTMLContent();
			
			// Here, the SwingWorker's get method returns an item
			// of the same type as specified as the first type parameter
			// given to the SwingWorker class.
			ArrayList<String> results = new ArrayList<String>(); // get();
			results.add(str);
			/*
			for (Integer i : results){
				listModel.addElement(i.toString());
			}
			 */
			
			// repaint();
		} catch (Exception e) {
			System.out.println("Caught an exception: " + e);
		}
	}

	public String getHTMLContent() {
		//
		/*
		NOT allowed, we have to call it ONLY in done
		if (webBrowser!=null){
			htmlContent = webBrowser.getHTMLContent() ;
		}else{
			htmlContent = "" ;
			System.out.println("BrowserWorker met an undefined WebBrowser (=null)!");
		}
		*/
		return htmlContent;
	}

	

}
